@powerhousedao/powerhouse-vetra-packages 6.2.3-dev.5 → 6.2.3-dev.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/dist/browser/assets/{entry-5_Eh4a2Z.js → entry-E7pSm84X.js} +111 -7
  2. package/dist/browser/assets/{projection-entry-5PVbP10h.js → projection-entry-UE4mfnXc.js} +99 -21
  3. package/dist/browser/document-models/index.js +2 -1
  4. package/dist/browser/{documents-J_l59mSV.js → documents-CRzouuNR.js} +631 -752
  5. package/dist/browser/documents-CRzouuNR.js.map +1 -0
  6. package/dist/browser/editor-C7KBR_ar.js +4676 -0
  7. package/dist/browser/editor-C7KBR_ar.js.map +1 -0
  8. package/dist/browser/{editor-Cbl_EDjI.js → editor-CiR6XQBO.js} +4 -5
  9. package/dist/browser/{editor-Cbl_EDjI.js.map → editor-CiR6XQBO.js.map} +1 -1
  10. package/dist/browser/editors/document-model-editor/module.js +1 -1
  11. package/dist/browser/editors/document-model-editor/module.js.map +1 -1
  12. package/dist/browser/editors/generic-drive-explorer/index.js +81 -65
  13. package/dist/browser/editors/generic-drive-explorer/index.js.map +1 -1
  14. package/dist/browser/editors/generic-drive-explorer/module.js +1 -1
  15. package/dist/browser/editors/generic-drive-explorer/module.js.map +1 -1
  16. package/dist/browser/folder-view-DSgXN79D.js +4409 -0
  17. package/dist/browser/folder-view-DSgXN79D.js.map +1 -0
  18. package/dist/browser/{graphql-editor-BcL3-Zha.js → graphql-editor-Cgi5UOrF.js} +98 -88
  19. package/dist/browser/graphql-editor-Cgi5UOrF.js.map +1 -0
  20. package/dist/{node/hooks-D0DcS3MV.mjs → browser/hooks-eQxBX7g4.js} +824 -444
  21. package/dist/browser/{hooks-KKcNp2X0.js.map → hooks-eQxBX7g4.js.map} +1 -1
  22. package/dist/browser/index.js +137 -34
  23. package/dist/browser/index.js.map +1 -1
  24. package/dist/browser/{json-editor-DHXQRIN5.js → json-editor-DfRD-pfk.js} +8 -9
  25. package/dist/browser/{json-editor-DHXQRIN5.js.map → json-editor-DfRD-pfk.js.map} +1 -1
  26. package/dist/browser/{parser-CkF6Qt8V.js → parser-DtbeHA3H.js} +7 -6
  27. package/dist/browser/{parser-CkF6Qt8V.js.map → parser-DtbeHA3H.js.map} +1 -1
  28. package/dist/browser/rolldown-runtime-DC62tzP2.js +33 -0
  29. package/dist/browser/src-CrUksCLW-B2dkRdgq.js +5254 -0
  30. package/dist/browser/src-CrUksCLW-B2dkRdgq.js.map +1 -0
  31. package/dist/browser/state-schemas-B5Bk_l1s.js +696 -0
  32. package/dist/browser/state-schemas-B5Bk_l1s.js.map +1 -0
  33. package/dist/browser/tslib.es6-Cno80yFJ.js +32 -0
  34. package/dist/browser/tslib.es6-Cno80yFJ.js.map +1 -0
  35. package/dist/node/document-models/index.mjs +2 -1
  36. package/dist/node/documents-D70S9PZL.mjs +17 -0
  37. package/dist/node/documents-D70S9PZL.mjs.map +1 -0
  38. package/dist/node/editor-96sMeumV.mjs +4597 -0
  39. package/dist/node/editor-96sMeumV.mjs.map +1 -0
  40. package/dist/node/{editor-DG1q4Y55.mjs → editor-wqvKwcO5.mjs} +4 -5
  41. package/dist/node/{editor-DG1q4Y55.mjs.map → editor-wqvKwcO5.mjs.map} +1 -1
  42. package/dist/node/editors/document-model-editor/module.mjs +1 -1
  43. package/dist/node/editors/document-model-editor/module.mjs.map +1 -1
  44. package/dist/node/editors/generic-drive-explorer/index.mjs +26 -21
  45. package/dist/node/editors/generic-drive-explorer/index.mjs.map +1 -1
  46. package/dist/node/editors/generic-drive-explorer/module.mjs +1 -1
  47. package/dist/node/editors/generic-drive-explorer/module.mjs.map +1 -1
  48. package/dist/node/folder-view-ktfv2Cvw.mjs +4409 -0
  49. package/dist/node/folder-view-ktfv2Cvw.mjs.map +1 -0
  50. package/dist/node/{graphql-BfAoPeWM.mjs → graphql-Dp4j7rmx.mjs} +50 -49
  51. package/dist/node/{graphql-BfAoPeWM.mjs.map → graphql-Dp4j7rmx.mjs.map} +1 -1
  52. package/dist/node/{graphql-editor-B-XIb6az.mjs → graphql-editor-CBJXEY_C.mjs} +77 -63
  53. package/dist/node/graphql-editor-CBJXEY_C.mjs.map +1 -0
  54. package/dist/{browser/hooks-KKcNp2X0.js → node/hooks-C2b46djt.mjs} +824 -444
  55. package/dist/node/{hooks-D0DcS3MV.mjs.map → hooks-C2b46djt.mjs.map} +1 -1
  56. package/dist/node/index.mjs +158 -35
  57. package/dist/node/index.mjs.map +1 -1
  58. package/dist/node/{json-editor-DB0vi6tV.mjs → json-editor-DaqHARBD.mjs} +8 -9
  59. package/dist/node/{json-editor-DB0vi6tV.mjs.map → json-editor-DaqHARBD.mjs.map} +1 -1
  60. package/dist/node/{schema-context-DL8jhi_d.mjs → schema-context-CojjnSE6.mjs} +6 -5
  61. package/dist/node/schema-context-CojjnSE6.mjs.map +1 -0
  62. package/dist/node/src-CrUksCLW-TvF37aMo.mjs +5935 -0
  63. package/dist/node/src-CrUksCLW-TvF37aMo.mjs.map +1 -0
  64. package/dist/node/state-schemas-BHuo0GPl.mjs +698 -0
  65. package/dist/node/state-schemas-BHuo0GPl.mjs.map +1 -0
  66. package/dist/node/{main-B1tRsYOp.mjs → tslib.es6-VORZjfk3.mjs} +40 -202
  67. package/dist/node/tslib.es6-VORZjfk3.mjs.map +1 -0
  68. package/package.json +12 -11
  69. package/dist/browser/button-CuO8Gh3v.js +0 -696
  70. package/dist/browser/button-CuO8Gh3v.js.map +0 -1
  71. package/dist/browser/connect-BtHSAuSc.js +0 -14328
  72. package/dist/browser/connect-BtHSAuSc.js.map +0 -1
  73. package/dist/browser/dist-B4FWbuEM.js +0 -4148
  74. package/dist/browser/dist-B4FWbuEM.js.map +0 -1
  75. package/dist/browser/dist-BAJ5nRDl.js +0 -2711
  76. package/dist/browser/dist-BAJ5nRDl.js.map +0 -1
  77. package/dist/browser/dist-D69hfRZN.js +0 -4641
  78. package/dist/browser/dist-D69hfRZN.js.map +0 -1
  79. package/dist/browser/document-drive-BEXJ-rHp.js +0 -8277
  80. package/dist/browser/document-drive-BEXJ-rHp.js.map +0 -1
  81. package/dist/browser/documents-J_l59mSV.js.map +0 -1
  82. package/dist/browser/editor-mNThkZOv.js +0 -1809
  83. package/dist/browser/editor-mNThkZOv.js.map +0 -1
  84. package/dist/browser/folder-view-D8AkN1Oj.js +0 -232
  85. package/dist/browser/folder-view-D8AkN1Oj.js.map +0 -1
  86. package/dist/browser/graphql-editor-BcL3-Zha.js.map +0 -1
  87. package/dist/browser/lib-ewnRj2dJ.js +0 -209
  88. package/dist/browser/lib-ewnRj2dJ.js.map +0 -1
  89. package/dist/browser/printer-CEYr4JOg.js +0 -604
  90. package/dist/browser/printer-CEYr4JOg.js.map +0 -1
  91. package/dist/browser/schema-context-ZyeclQwy.js +0 -69
  92. package/dist/browser/schema-context-ZyeclQwy.js.map +0 -1
  93. package/dist/browser/state-schemas-C4F8lReN.js +0 -298
  94. package/dist/browser/state-schemas-C4F8lReN.js.map +0 -1
  95. package/dist/node/button-Da7CxMn7.mjs +0 -678
  96. package/dist/node/button-Da7CxMn7.mjs.map +0 -1
  97. package/dist/node/connect-B6IQsY6u.mjs +0 -15022
  98. package/dist/node/connect-B6IQsY6u.mjs.map +0 -1
  99. package/dist/node/dist-CzYOpeXN.mjs +0 -2711
  100. package/dist/node/dist-CzYOpeXN.mjs.map +0 -1
  101. package/dist/node/dist-DT7jI9ol.mjs +0 -4148
  102. package/dist/node/dist-DT7jI9ol.mjs.map +0 -1
  103. package/dist/node/dist-hd-KLWy7.mjs +0 -4649
  104. package/dist/node/dist-hd-KLWy7.mjs.map +0 -1
  105. package/dist/node/document-drive-CkV9NvD7.mjs +0 -8294
  106. package/dist/node/document-drive-CkV9NvD7.mjs.map +0 -1
  107. package/dist/node/documents-DCf53bzO.mjs +0 -747
  108. package/dist/node/documents-DCf53bzO.mjs.map +0 -1
  109. package/dist/node/editor-C93fdI28.mjs +0 -1809
  110. package/dist/node/editor-C93fdI28.mjs.map +0 -1
  111. package/dist/node/folder-view-BGabHV7H.mjs +0 -232
  112. package/dist/node/folder-view-BGabHV7H.mjs.map +0 -1
  113. package/dist/node/graphql-editor-B-XIb6az.mjs.map +0 -1
  114. package/dist/node/main-B1tRsYOp.mjs.map +0 -1
  115. package/dist/node/schema-context-DL8jhi_d.mjs.map +0 -1
  116. package/dist/node/state-schemas-BGsgtEG1.mjs +0 -299
  117. package/dist/node/state-schemas-BGsgtEG1.mjs.map +0 -1
@@ -1,8 +1,103 @@
1
- import { o as instrumentPgPool } from "./drive-container-types-yZrksiJR.js";
2
- import { n as errorToInfo, t as createForwardingLogger } from "./forwarding-logger-BBkMSxuJ.js";
3
- import { n as defaultLoadFactory, t as buildWorkerExecutor } from "./build-worker-executor-DnU3ZU4H.js";
1
+ import { D as CollectionMembershipCache, E as DocumentMetaCache, St as ReactorEventTypes, a as REACTOR_SCHEMA, d as KyselyKeyframeStore, f as EventBus, l as instrumentPgPool, m as KyselyOperationIndex, n as errorToInfo, p as KyselyWriteCache, t as createForwardingLogger, u as KyselyOperationStore } from "./forwarding-logger-ByfBFgMS.js";
2
+ import { a as KyselyExecutionScope, n as SimpleJobExecutor, t as DEFAULT_DRIVE_CONTAINER_TYPES } from "./drive-container-types-Ci1pdv4X.js";
3
+ import { n as loadDocumentModelSpec, r as DocumentModelRegistry, t as defaultLoadFactory } from "./load-spec-ZLjuyhxz.js";
4
4
  import { ConsoleLogger } from "document-model";
5
5
  import { isMainThread, parentPort } from "node:worker_threads";
6
+ //#region src/executor/worker/build-worker-executor.ts
7
+ async function loadModelManifest(entries, loadFactory, registry, logger) {
8
+ for (const entry of entries) {
9
+ let module;
10
+ try {
11
+ module = await loadFactory(entry.spec);
12
+ } catch (error) {
13
+ logger.error("worker failed to load document model: @entry @error", entry, error);
14
+ throw error;
15
+ }
16
+ const [result] = registry.registerModules(module);
17
+ if (result.status === "error") {
18
+ logger.error("worker failed to register document model: @entry @error", entry, result.error);
19
+ throw result.error;
20
+ }
21
+ }
22
+ }
23
+ /**
24
+ * Assembles the in-worker storage stack plus a {@link SimpleJobExecutor}
25
+ * bound to a pre-built Kysely instance. The parent owns the wire protocol
26
+ * and routing; the worker owns everything below `SimpleJobExecutor`.
27
+ *
28
+ * The local event bus exists only to satisfy the executor's contract: its
29
+ * JOB_WRITE_READY emissions are captured here and shipped to the parent
30
+ * via {@link WorkerExecutorStack.takeLastWriteReady}.
31
+ */
32
+ async function buildWorkerExecutor(options) {
33
+ const { init, database: baseDatabase, logger } = options;
34
+ const driveContainerTypes = options.driveContainerTypes ?? DEFAULT_DRIVE_CONTAINER_TYPES;
35
+ const loadFactory = options.loadFactory ?? defaultLoadFactory;
36
+ const registry = new DocumentModelRegistry();
37
+ await loadModelManifest(init.models, loadFactory, registry, logger);
38
+ let signer;
39
+ if (init.signer) try {
40
+ signer = await loadFactory(init.signer);
41
+ } catch (error) {
42
+ logger.error("worker failed to load signer: @spec @error", init.signer.module, error);
43
+ throw error;
44
+ }
45
+ let trustPolicy;
46
+ if (init.trustPolicy) try {
47
+ trustPolicy = await loadFactory(init.trustPolicy);
48
+ } catch (error) {
49
+ logger.error("worker failed to load trust policy: @spec @error", init.trustPolicy.module, error);
50
+ throw error;
51
+ }
52
+ const database = baseDatabase.withSchema(REACTOR_SCHEMA);
53
+ const operationStore = new KyselyOperationStore(database);
54
+ const keyframeStore = new KyselyKeyframeStore(database);
55
+ const writeCache = new KyselyWriteCache(keyframeStore, operationStore, registry, {
56
+ maxDocuments: 100,
57
+ ringBufferSize: 10,
58
+ keyframeInterval: 10
59
+ });
60
+ await writeCache.startup();
61
+ const operationIndex = new KyselyOperationIndex(database);
62
+ const documentMetaCache = new DocumentMetaCache(operationStore, { maxDocuments: 1e3 });
63
+ await documentMetaCache.startup();
64
+ const collectionMembershipCache = new CollectionMembershipCache(operationIndex);
65
+ const executionScope = new KyselyExecutionScope(database, operationStore, operationIndex, keyframeStore, writeCache, documentMetaCache, collectionMembershipCache);
66
+ const eventBus = new EventBus();
67
+ let lastWriteReady = null;
68
+ eventBus.subscribe(ReactorEventTypes.JOB_WRITE_READY, (_t, event) => {
69
+ lastWriteReady = {
70
+ operations: event.operations,
71
+ jobMeta: event.jobMeta
72
+ };
73
+ });
74
+ let signatureRefusals = [];
75
+ eventBus.subscribe(ReactorEventTypes.SIGNATURE_REFUSED, (_t, event) => {
76
+ signatureRefusals.push(event);
77
+ });
78
+ const executorConfig = options.executorConfig ?? {};
79
+ return {
80
+ executor: new SimpleJobExecutor(logger, registry, operationStore, eventBus, writeCache, operationIndex, documentMetaCache, collectionMembershipCache, driveContainerTypes, executorConfig, executionScope, signer, trustPolicy),
81
+ registry,
82
+ takeLastWriteReady() {
83
+ const captured = lastWriteReady;
84
+ lastWriteReady = null;
85
+ return captured;
86
+ },
87
+ takeSignatureRefusals() {
88
+ const captured = signatureRefusals;
89
+ signatureRefusals = [];
90
+ return captured;
91
+ },
92
+ evictPurged(documentIds) {
93
+ for (const documentId of documentIds) {
94
+ writeCache.invalidate(documentId);
95
+ documentMetaCache.invalidate(documentId);
96
+ }
97
+ }
98
+ };
99
+ }
100
+ //#endregion
6
101
  //#region src/executor/worker/run-worker.ts
7
102
  const POOL_SAMPLE_INTERVAL_MS = 1e3;
8
103
  async function defaultCreateDatabase(config, workerId) {
@@ -38,7 +133,7 @@ async function defaultCreateDatabase(config, workerId) {
38
133
  /**
39
134
  * Drives the worker's message loop. Owns lifecycle of the database handle
40
135
  * and executor stack. The default factories build a real Postgres pool and
41
- * use dynamic `import()` for model/verifier specs; tests inject overrides
136
+ * use dynamic `import()` for model/signer specs; tests inject overrides
42
137
  * for an in-process PGlite path.
43
138
  */
44
139
  function runWorker(parentPort, overrides = {}) {
@@ -51,6 +146,7 @@ function runWorker(parentPort, overrides = {}) {
51
146
  let pendingPoolSamples = [];
52
147
  let detachPoolListener = null;
53
148
  const activeLoadFactory = overrides.loadFactory ?? defaultLoadFactory;
149
+ const loadModelSpec = overrides.loadFactory ? async (spec) => await activeLoadFactory(spec) : loadDocumentModelSpec;
54
150
  function post(msg) {
55
151
  parentPort.postMessage(msg);
56
152
  }
@@ -146,11 +242,16 @@ function runWorker(parentPort, overrides = {}) {
146
242
  return;
147
243
  }
148
244
  try {
245
+ const result = await executorStack.executor.executeJob(job);
246
+ const writeReady = executorStack.takeLastWriteReady();
247
+ const signatureRefusals = executorStack.takeSignatureRefusals();
149
248
  post({
150
249
  type: "result",
151
250
  correlationId,
152
- result: await executorStack.executor.executeJob(job),
153
- writeReady: executorStack.takeLastWriteReady() ?? void 0
251
+ result,
252
+ writeReady: writeReady ?? void 0,
253
+ signatureRefusals: signatureRefusals.length > 0 ? signatureRefusals : void 0,
254
+ error: !result.success && result.error ? errorToInfo(result.error) : void 0
154
255
  });
155
256
  } catch (error) {
156
257
  post({
@@ -178,7 +279,7 @@ function runWorker(parentPort, overrides = {}) {
178
279
  }
179
280
  let module;
180
281
  try {
181
- module = await activeLoadFactory(msg.model.spec);
282
+ module = await loadModelSpec(msg.model.spec);
182
283
  } catch (error) {
183
284
  post({
184
285
  type: "model-load-failed",
@@ -277,6 +378,9 @@ function runWorker(parentPort, overrides = {}) {
277
378
  });
278
379
  });
279
380
  break;
381
+ case "evict-purged":
382
+ executorStack?.evictPurged(msg.documentIds);
383
+ break;
280
384
  default: {
281
385
  const raw = msg;
282
386
  if (raw["type"] === "__test_throw") {
@@ -1,11 +1,23 @@
1
- import { _ as DocumentMetaCache, c as KyselyKeyframeStore, g as KyselyOperationIndex, h as KyselyWriteCache, l as DocumentModelRegistry, m as EventBus, n as REACTOR_SCHEMA, o as instrumentPgPool, s as KyselyOperationStore, v as CollectionMembershipCache } from "./drive-container-types-yZrksiJR.js";
2
- import { n as ReactorEventTypes } from "./types-DMKLa0Ok.js";
3
- import { i as KyselyDocumentView, n as ConsistencyTracker, s as ReadModelCoordinator, t as KyselyDocumentIndexer } from "./document-indexer-C5Gsa1B3.js";
4
- import { n as errorToInfo, t as createForwardingLogger } from "./forwarding-logger-BBkMSxuJ.js";
5
- import { n as defaultLoadFactory } from "./build-worker-executor-DnU3ZU4H.js";
1
+ import { D as CollectionMembershipCache, E as DocumentMetaCache, S as createKyselyWatermarkProbe, St as ReactorEventTypes, a as REACTOR_SCHEMA, d as KyselyKeyframeStore, f as EventBus, l as instrumentPgPool, m as KyselyOperationIndex, n as errorToInfo, p as KyselyWriteCache, t as createForwardingLogger, u as KyselyOperationStore, v as findPurged, x as SettledWatermark } from "./forwarding-logger-ByfBFgMS.js";
2
+ import { r as DocumentModelRegistry, t as defaultLoadFactory } from "./load-spec-ZLjuyhxz.js";
3
+ import { a as KyselyDocumentView, c as ReadModelCoordinator, f as BaseReadModel, n as ConsistencyTracker, t as KyselyDocumentIndexer, y as CatchUpScheduler } from "./document-indexer-DwAMDVRI.js";
4
+ import { isPurgeMarker } from "@powerhousedao/shared/document-model";
6
5
  import { ConsoleLogger } from "document-model";
7
6
  import { isMainThread, parentPort } from "node:worker_threads";
8
7
  //#region src/projection/projection-worker/build-projection-stack.ts
8
+ /**
9
+ * In-worker projection stack builder.
10
+ *
11
+ * Mirrors {@link buildWorkerExecutor} but for the projection-side
12
+ * read models. The worker owns one full copy of the storage stack — read
13
+ * cache, operation index, document-meta cache — bound to its own
14
+ * pg.Pool/Kysely, plus an in-process `ReadModelCoordinator` that
15
+ * subscribes to a local `EventBus`.
16
+ *
17
+ * The host relays JOB_WRITE_READY into the local bus by calling
18
+ * `relayWriteReady`, and forwards the local bus's JOB_READ_READY plus
19
+ * READMODEL_* events back to the host bus via the IPC bridge.
20
+ */
9
21
  async function loadModelManifest(entries, loadFactory, registry, logger) {
10
22
  for (const entry of entries) {
11
23
  let module;
@@ -22,14 +34,11 @@ async function loadModelManifest(entries, loadFactory, registry, logger) {
22
34
  }
23
35
  }
24
36
  }
25
- function instantiateReadModel(kind, database, operationStore, operationIndex, writeCache) {
37
+ function instantiateReadModel(kind, database, operationStore, operationIndex, writeCache, indexing) {
26
38
  switch (kind) {
27
- case "document-view": return new KyselyDocumentView(database, operationStore, operationIndex, writeCache, new ConsistencyTracker(), false);
28
- case "document-indexer": return new KyselyDocumentIndexer(database, operationIndex, writeCache, new ConsistencyTracker());
29
- default: {
30
- const exhaustive = kind;
31
- throw new Error(`unknown built-in read model kind: ${String(exhaustive)}`);
32
- }
39
+ case "document-view": return new KyselyDocumentView(database, operationStore, operationIndex, writeCache, new ConsistencyTracker(), "NotFound", indexing);
40
+ case "document-indexer": return new KyselyDocumentIndexer(database, operationIndex, writeCache, new ConsistencyTracker(), indexing);
41
+ default: throw new Error(`unknown built-in read model kind: ${String(kind)}`);
33
42
  }
34
43
  }
35
44
  async function initReadModels(models, logger) {
@@ -44,6 +53,32 @@ async function initReadModels(models, logger) {
44
53
  }
45
54
  }
46
55
  }
56
+ /** Posts what each sweep applied, so the host's tracker for the model advances. */
57
+ function relaySweeps(model, events, onSwept) {
58
+ return {
59
+ get consumerId() {
60
+ return model.consumerId;
61
+ },
62
+ get appliedThrough() {
63
+ return model.appliedThrough;
64
+ },
65
+ get trackedAbove() {
66
+ return model.trackedAbove;
67
+ },
68
+ async sweep(settledThrough, present, signal) {
69
+ const coordinates = [];
70
+ const unsubscribe = model.onSwept((swept) => coordinates.push(...swept));
71
+ try {
72
+ const result = await model.sweep(settledThrough, present, signal);
73
+ if (coordinates.length > 0 || result.to > result.from || result.replayed > 0 || result.blockedAt !== void 0) events.onReadModelSwept(model.name, coordinates, result);
74
+ await onSwept(coordinates);
75
+ return result;
76
+ } finally {
77
+ unsubscribe();
78
+ }
79
+ }
80
+ };
81
+ }
47
82
  async function buildProjectionStack(options) {
48
83
  const { init, database: baseDatabase, logger, events } = options;
49
84
  const loadFactory = options.loadFactory ?? defaultLoadFactory;
@@ -51,18 +86,44 @@ async function buildProjectionStack(options) {
51
86
  await loadModelManifest(init.models, loadFactory, registry, logger);
52
87
  const database = baseDatabase.withSchema(REACTOR_SCHEMA);
53
88
  const operationStore = new KyselyOperationStore(database);
54
- const writeCache = new KyselyWriteCache(new KyselyKeyframeStore(database), operationStore, registry, {
89
+ const keyframeStore = new KyselyKeyframeStore(database);
90
+ const writeCache = new KyselyWriteCache(keyframeStore, operationStore, registry, {
55
91
  maxDocuments: 100,
56
92
  ringBufferSize: 10,
57
93
  keyframeInterval: 10
58
94
  });
59
95
  await writeCache.startup();
60
96
  const operationIndex = new KyselyOperationIndex(database);
61
- await new DocumentMetaCache(operationStore, { maxDocuments: 1e3 }).startup();
97
+ const documentMetaCache = new DocumentMetaCache(operationStore, { maxDocuments: 1e3 });
98
+ await documentMetaCache.startup();
62
99
  new CollectionMembershipCache(operationIndex);
63
- const preReady = init.preReadyKinds.map((kind) => instantiateReadModel(kind, database, operationStore, operationIndex, writeCache));
64
- const postReady = init.postReadyKinds.map((kind) => instantiateReadModel(kind, database, operationStore, operationIndex, writeCache));
65
- await initReadModels([...preReady, ...postReady], logger);
100
+ const evict = (documentIds) => {
101
+ for (const documentId of documentIds) {
102
+ writeCache.invalidate(documentId);
103
+ documentMetaCache.invalidate(documentId);
104
+ }
105
+ };
106
+ const evictSweptMarkers = async (coordinates) => {
107
+ const candidates = coordinates.filter((c) => c.scope === "document" && c.operationIndex === 0).map((c) => c.documentId);
108
+ if (candidates.length === 0) return;
109
+ let purged;
110
+ try {
111
+ purged = await findPurged(database, candidates);
112
+ } catch (error) {
113
+ logger.error("projection worker purge lookup failed: @error", error);
114
+ return;
115
+ }
116
+ evict(purged);
117
+ };
118
+ const preReady = init.preReadyKinds.map((kind) => instantiateReadModel(kind, database, operationStore, operationIndex, writeCache, init.indexing));
119
+ const postReady = init.postReadyKinds.map((kind) => instantiateReadModel(kind, database, operationStore, operationIndex, writeCache, init.indexing));
120
+ const watermark = new SettledWatermark(createKyselyWatermarkProbe(database), logger);
121
+ const catchUp = new CatchUpScheduler(watermark, operationIndex, init.catchUp, logger);
122
+ const models = [...preReady, ...postReady];
123
+ for (const model of models) if (model instanceof BaseReadModel) model.attachCatchUp(watermark, init.catchUp.maxTrackedAboveCursor);
124
+ await initReadModels(models, logger);
125
+ for (const model of models) if (model instanceof BaseReadModel) catchUp.addConsumer(relaySweeps(model, events, evictSweptMarkers), "projection");
126
+ catchUp.start();
66
127
  const eventBus = new EventBus();
67
128
  const subscriptions = [];
68
129
  subscriptions.push(eventBus.subscribe(ReactorEventTypes.JOB_READ_READY, (_t, event) => {
@@ -80,19 +141,24 @@ async function buildProjectionStack(options) {
80
141
  registry,
81
142
  coordinator,
82
143
  eventBus,
144
+ writeCache,
83
145
  async relayWriteReady(event) {
146
+ evict(event.operations.filter((item) => isPurgeMarker(item)).map((item) => item.context.documentId));
84
147
  await eventBus.emit(ReactorEventTypes.JOB_WRITE_READY, event);
85
148
  },
86
149
  getChainDepth() {
87
150
  return coordinator.getChainDepth();
88
151
  },
152
+ catchUpStatus() {
153
+ return catchUp.status();
154
+ },
89
155
  async drain() {
90
156
  await coordinator.drain();
91
157
  },
92
- shutdown() {
158
+ async shutdown() {
159
+ await catchUp.stop();
93
160
  coordinator.stop();
94
161
  for (const unsub of subscriptions) unsub();
95
- return Promise.resolve();
96
162
  }
97
163
  };
98
164
  }
@@ -213,6 +279,11 @@ function runProjectionWorker(parentPort, overrides = {}) {
213
279
  if (intervalMs <= 0) return;
214
280
  depthTimer = setInterval(() => {
215
281
  if (!stack) return;
282
+ post({
283
+ type: "catchup-status",
284
+ shardId,
285
+ status: stack.catchUpStatus()
286
+ });
216
287
  const depth = stack.getChainDepth();
217
288
  if (depth === lastReportedDepth) return;
218
289
  lastReportedDepth = depth;
@@ -261,6 +332,15 @@ function runProjectionWorker(parentPort, overrides = {}) {
261
332
  success: event.success
262
333
  });
263
334
  },
335
+ onReadModelSwept: (readModelName, coordinates, result) => {
336
+ post({
337
+ type: "readmodel-swept",
338
+ shardId,
339
+ readModelName,
340
+ coordinates,
341
+ result
342
+ });
343
+ },
264
344
  onBatchCompleted: (event) => {
265
345
  post({
266
346
  type: "readmodel-batch-completed",
@@ -380,8 +460,6 @@ function runProjectionWorker(parentPort, overrides = {}) {
380
460
  });
381
461
  process.exit(0);
382
462
  });
383
- break;
384
- default: break;
385
463
  }
386
464
  }
387
465
  parentPort.on("message", handleParentMessage);
@@ -1,2 +1,3 @@
1
- import { p as documentModelDocumentModelModule, r as driveDocumentModelModule } from "../document-drive-BEXJ-rHp.js";
1
+ import { documentModelDocumentModelModule } from "document-model";
2
+ import { driveDocumentModelModule } from "@powerhousedao/shared/document-drive";
2
3
  export { documentModelDocumentModelModule, driveDocumentModelModule };